package cn.jsj.invite.service.impl;

import cn.hutool.core.util.IdUtil;
import cn.jsj.invite.exception.CustomException;
import cn.jsj.invite.pojo.PictureFileTypeEnum;
import cn.jsj.invite.service.PictureFileService;
import io.micrometer.core.instrument.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

@Slf4j
@Service
public class PictureFileServiceImpl implements PictureFileService {

    @Value("${photo.save-path}")
    private String prefixFilePath;

    /**
     * 保存图片文件
     *
     * @param multipartFile 文件信息
     * @return 图片相对地址
     */
    @Override
    public String savePictureFile(MultipartFile multipartFile) {
        String fileSuffixName = getFileNameSuffix(multipartFile);
        if (Boolean.TRUE.equals(PictureFileTypeEnum.isEnableFileNameSuffix(fileSuffixName))) {
            String keyId = IdUtil.fastSimpleUUID();
            String relativePath = keyId + "." + fileSuffixName;
            File filePath = new File(prefixFilePath + relativePath);
            log.info("文件保存路径：{}", filePath.getPath());
            try {
                multipartFile.transferTo(filePath);
            } catch (IOException | IllegalStateException e) {
                e.printStackTrace();
                throw new CustomException("文件写入失败");
            }
            return relativePath;
        } else {
            throw new CustomException("错误的文件格式");
        }
    }

    /**
     * 下载图片
     *
     * @param relativePath 相对路径
     * @param response     响应接口
     */
    @Override
    public void getPictureFile(String relativePath, HttpServletResponse response) {
        if (StringUtils.isBlank(relativePath)) {
            throw new CustomException("无效的相对路径");
        }
        File filePath = new File(prefixFilePath + relativePath);
        if (filePath.isDirectory()) {
            throw new CustomException("错误的文件地址信息");
        }
        // 设置文件响应头：最后一个参数是设置下载文件名
        response.setHeader("Content-Disposition", "attachment;filename=" + filePath.getName());

        // 设置响应头，文件大小
        response.setHeader("Content-Length", String.valueOf(filePath.length()));
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(filePath);
            int b = 0;
            byte[] buffer = new byte[1024];
            while (b != -1) {
                b = inputStream.read(buffer);
                if (b != -1) {
                    response.getOutputStream().write(buffer, 0, b);
                }
            }
        } catch (FileNotFoundException e) {
            throw new CustomException("文件不存在");
        } catch (IOException e) {
            throw new CustomException("文件输出终止");
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                response.getOutputStream().flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取文件后缀名
     *
     * @param multipartFile 文件信息
     * @return 文件后缀名
     */
    @Override
    public String getFileNameSuffix(MultipartFile multipartFile) {
        if (multipartFile == null || multipartFile.isEmpty()) {
            throw new CustomException("无效的文件信息");
        }
        String allFilePath = multipartFile.getOriginalFilename();
        if (StringUtils.isBlank(allFilePath)) {
            throw new CustomException("请填写有效文件路径");
        }
        // 获取用户上传的文件的后缀名
        String[] fileNames = allFilePath.split("\\.");
        return fileNames[fileNames.length - 1];
    }
}
